﻿namespace Suture.Tests
{
    using NUnit.Framework;

    using Suture.StubGeneration;

    [TestFixture]
    public class SimpleDynamicProxyTests
    {
        [Test]
        public void Should_create_stub_instance_of_interface()
        {
            var stub = SimpleDynamicProxy.CreateStub<IEmptyInterface>();
            Assert.That(stub, Is.Not.Null);
        }

        [Test]
        public void Should_return_default_values_for_property_getter()
        {
            var stub = SimpleDynamicProxy.CreateStub<IInterfaceWithPropertyGetter>();
            Assert.That(stub.Property1, Is.EqualTo(0));
        }

        [Test]
        public void Should_be_able_to_set_value_on_property()
        {
            const int expected = 10;
            var stub = SimpleDynamicProxy.CreateStub<IInterfaceWithPropertyGetterAndSetter>();
            stub.Property1 = expected;
            Assert.That(stub.Property1, Is.EqualTo(expected));
        }

        [Test]
        public void Should_stub_void_methods()
        {
            var stub = SimpleDynamicProxy.CreateStub<IInterfaceWithVoidMethod>();
            stub.Method1();
        }

        [Test]
        public void Should_stub_value_return_type_methods()
        {
            var stub = SimpleDynamicProxy.CreateStub<IInterfaceWithValueTypeReturn>();
            var retval = stub.Method1();

            Assert.That(retval, Is.EqualTo(0));
        }

        [Test]
        public void Should_stub_reference_return_type_methods()
        {
            var stub = SimpleDynamicProxy.CreateStub<IInterfaceWithReferenceTypeReturn>();
            var retval = stub.Method1();

            Assert.That(retval, Is.EqualTo(null));
        }

        public interface IEmptyInterface
        {
        }

        public interface IInterfaceWithPropertyGetter
        {
            int Property1 { get; }
        }

        public interface IInterfaceWithPropertyGetterAndSetter
        {
            int Property1 { get; set; }
        }

        public interface IInterfaceWithVoidMethod
        {
            void Method1();
        }

        public interface IInterfaceWithValueTypeReturn
        {
            int Method1();
        }

        public interface IInterfaceWithReferenceTypeReturn
        {
            object Method1();
        }
    }
}